// Kony

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "Data/CharacterClassInfo.h"
#include "BaseAbilitySystemLibrary.generated.h"

class ULoadScreenSaveGame;
class UOverlayWidgetController;
class UAttributeMenuWidgetController;
class USpellMenuWidgetController;
class UAbilitySystemComponent;
struct FWidgetControllerParams;

/**
 * 能力系统蓝函数库
 * 函数库里的函数必须是静态的
 * WorldContextObject 参数必须是UObject指针
 */
UCLASS()
class GASC_HUANLING_API UBaseAbilitySystemLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()
public:
	/*
	 * 用户小组件控制器
	 */
	//通用获取小组件控制器 蓝图库
	UFUNCTION(BlueprintPure, Category = "BaseAbilitySystemLibrary|WidgetController", meta = (DefaultToSelf = "WorldContextObject"))
	static bool MakeWidgetControllerParams(const UObject* WorldContextObject, FWidgetControllerParams& OutWCParams, ABaseHUD*& OutBaseHUD);
	//覆盖层小部件控制器 蓝函数库
	UFUNCTION(BlueprintPure, Category = "BaseAbilitySystemLibrary|WidgetController", meta = (DefaultToSelf = "WorldContextObject"))
	static UOverlayWidgetController* GetBaseOverlayWidgetController(const UObject* WorldContextObject);
	//玩家信息属性菜单小部件控制器 蓝函数库
	UFUNCTION(BlueprintPure, Category = "BaseAbilitySystemLibrary|WidgetController", meta = (DefaultToSelf = "WorldContextObject"))
	static UAttributeMenuWidgetController* GetBaseAttributeMenuWidgetController(const UObject* WorldContextObject);
	//玩家信息属性菜单小部件控制器 蓝函数库
	UFUNCTION(BlueprintPure, Category = "BaseAbilitySystemLibrary|WidgetController", meta = (DefaultToSelf = "WorldContextObject"))
	static USpellMenuWidgetController* GetBaseSpellMenuWidgetController(const UObject* WorldContextObject);
	/*
	 * 能力系统初始化 属性信息和职业能力信息
	 */
	//初始化默认属性信息
	UFUNCTION(BlueprintCallable, Category = "BaseAbilitySystemLibrary|CharacterClassDefaults")
	static void InitializeDefaultAttributes(const UObject* WorldContextObject, ECharacterClass CharacterClass, float Level,UAbilitySystemComponent* ASC);
	//从存档中读取主属性 初始化主属性信息
	UFUNCTION(BlueprintCallable, Category = "BaseAbilitySystemLibrary|CharacterClassDefaults")
	static void InitializeDefaultAttributesFromSaveData(const UObject* WorldContextObject,UAbilitySystemComponent* ASC,ULoadScreenSaveGame* SaveGame);
	
	//初始化敌人游戏能力
	UFUNCTION(BlueprintCallable, Category = "BaseAbilitySystemLibrary|CharacterClassDefaults")
	static void GvieStartupAbilities(const UObject* WorldContextObject, UAbilitySystemComponent* ASC, ECharacterClass CharacterClass);
	//获取角色各类信息参数 用于获取给角色设置的各种属性和伤害相关曲线系数表
	UFUNCTION(BlueprintCallable, Category = "BaseAbilitySystemLibrary|CharacterClassDefaults")
	static UCharacterClassInfo* GetCharacterClassInfo(const UObject* WorldContextObject);
	//获取能力信息
	UFUNCTION(BlueprintCallable, Category = "BaseAbilitySystemLibrary|CharacterClassDefaults")
	static UAbilityInfo* GetAbilityInfo(const UObject* WorldContextObject);

	/*
	 * 效果上下文获取器Geters 获取各种状态效果
	 */
	//获取是否格挡
	UFUNCTION(BlueprintPure, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static bool IsBlockedHit(const FGameplayEffectContextHandle& EffectContextHandle);
	//获取是否闪避
	UFUNCTION(BlueprintPure, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static bool IsDodgeHit(const FGameplayEffectContextHandle& EffectContextHandle);
	//获取是否吸收
	UFUNCTION(BlueprintPure, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static bool IsAbsorbHit(const FGameplayEffectContextHandle& EffectContextHandle);
	//获取是否暴击
	UFUNCTION(BlueprintPure, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static bool IsCriticalHit(const FGameplayEffectContextHandle& EffectContextHandle);
	//获取是否硬直
	UFUNCTION(BlueprintPure, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static bool IsStagger(const FGameplayEffectContextHandle& EffectContextHandle);
	//获取硬直值
	UFUNCTION(BlueprintPure, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static float GetStagger(const FGameplayEffectContextHandle& EffectContextHandle);
	//获取伤害类型
	UFUNCTION(BlueprintPure, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static FGameplayTag GetDamageType(const FGameplayEffectContextHandle& EffectContextHandle);
	//获取是否成功触发debuff
	UFUNCTION(BlueprintPure, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static bool IsSuccessfulDebuff(const FGameplayEffectContextHandle& EffectContextHandle);
	//获取异常伤害
	UFUNCTION(BlueprintPure, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static float GetDebuffDamage(const FGameplayEffectContextHandle& EffectContextHandle);
	//获取异常持续时间
	UFUNCTION(BlueprintPure, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static float GetDebuffDuration(const FGameplayEffectContextHandle& EffectContextHandle);
	//获取异常频率
	UFUNCTION(BlueprintPure, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static float GetDebuffFrequency(const FGameplayEffectContextHandle& EffectContextHandle);
	//获取击杀敌人死亡是冲击方向向量
	UFUNCTION(BlueprintPure, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static FVector GetDeathImpulse(const FGameplayEffectContextHandle& EffectContextHandle);
	//获取击退敌人方向向量
	UFUNCTION(BlueprintPure, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static FVector GetKnockbackForce(const FGameplayEffectContextHandle& EffectContextHandle);
	
	//获取是否是径向衰减伤害
	UFUNCTION(BlueprintPure, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static bool IsRadialDamage(const FGameplayEffectContextHandle& EffectContextHandle);
	//获取径向伤害内半径
	UFUNCTION(BlueprintPure, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static float GetRadialDamageInnerRadius(const FGameplayEffectContextHandle& EffectContextHandle);
	//获取径向伤害外半径
	UFUNCTION(BlueprintPure, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static float GetRadialDamageOuterRadius(const FGameplayEffectContextHandle& EffectContextHandle);
	//获取径向原点
	UFUNCTION(BlueprintPure, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static FVector GetRadialDamageOrigin(const FGameplayEffectContextHandle& EffectContextHandle);
	
	
	/*
	 * 效果上下文写入器 Setters, 写入各种状态效果
	 */
	//设置是否格挡，UPARAM(ref) 这个代表设置常量 可以在蓝图进行输入，否则如果不设置 就是一个输出引脚，并且不会影响在c++中是动态的变量
	UFUNCTION(BlueprintCallable, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static void SetIsBlockedHit(UPARAM(ref) FGameplayEffectContextHandle& EffectContextHandle, bool bInIsBlockedHit);
	//设置是否闪避
	UFUNCTION(BlueprintCallable, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static void SetIsDodgeHit(UPARAM(ref) FGameplayEffectContextHandle& EffectContextHandle, bool bInIsDodgeHit);
	//设置是否吸收
	UFUNCTION(BlueprintCallable, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static void SetIsAbsorbHit(UPARAM(ref) FGameplayEffectContextHandle& EffectContextHandle, bool bInIsAbsorbHit);
	//设置是否暴击
	UFUNCTION(BlueprintCallable, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static void SetIsCriticalHit(UPARAM(ref) FGameplayEffectContextHandle& EffectContextHandle, bool bInIsCriticalHit);
	//设置是否硬直
	UFUNCTION(BlueprintCallable, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static void SetIsStagger(UPARAM(ref) FGameplayEffectContextHandle& EffectContextHandle, bool bInIsStagger);
	//设置硬直值
	UFUNCTION(BlueprintCallable, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static void SetStagger(UPARAM(ref) FGameplayEffectContextHandle& EffectContextHandle, float InStagger);
	//设置伤害类型
	UFUNCTION(BlueprintCallable, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static void SetDamageType(UPARAM(ref) FGameplayEffectContextHandle& EffectContextHandle, const FGameplayTag& InDamageType);
	//设置是否成功触发debuff
	UFUNCTION(BlueprintCallable, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static void SetIsSuccessfulDebuff(UPARAM(ref) FGameplayEffectContextHandle& EffectContextHandle, bool bInIsSuccessfulDebuff);
	//设置异常伤害
	UFUNCTION(BlueprintCallable, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static void SetDebuffDamage(UPARAM(ref) FGameplayEffectContextHandle& EffectContextHandle, float InDebuffDamage);
	//设置异常持续时间
	UFUNCTION(BlueprintCallable, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static void SetDebuffDuration(UPARAM(ref) FGameplayEffectContextHandle& EffectContextHandle, float InDebuffDuration);
	//设置异常频率
	static void SetDebuffFrequency(UPARAM(ref) FGameplayEffectContextHandle& EffectContextHandle, float InDebuffFrequency);
	//设置击杀敌人死亡是冲击方向向量
	UFUNCTION(BlueprintCallable, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static void SetDeathImpulse(UPARAM(ref) FGameplayEffectContextHandle& EffectContextHandle, const FVector& InDeathImpulse);
	//设置击退敌人方向向量
	UFUNCTION(BlueprintCallable, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static void SetKnockbackForce(UPARAM(ref) FGameplayEffectContextHandle& EffectContextHandle, const FVector& InForce);
	//设置是否是径向伤害
	UFUNCTION(BlueprintCallable, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static void SetIsRadialDamage(UPARAM(ref) FGameplayEffectContextHandle& EffectContextHandle, bool bInIsRadialDamage);
	//设置径向伤害内半径
	UFUNCTION(BlueprintCallable, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static void SetRadialDamageInnerRadius(UPARAM(ref) FGameplayEffectContextHandle& EffectContextHandle, float InInnerRadius);
	//设置径向伤害外半径
	UFUNCTION(BlueprintCallable, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static void SetRadialDamageOuterRadius(UPARAM(ref) FGameplayEffectContextHandle& EffectContextHandle, float InOuterRadius);
	//设置径向原点
	UFUNCTION(BlueprintCallable, Category = "BaseAbilitySystemLibrary|GameplayEffect")
	static void SetRadialDamageOrigin(UPARAM(ref) FGameplayEffectContextHandle& EffectContextHandle, const FVector& InOrigin);
	
	
	/*
	 * 游戏机制 算法等
	 */
	//获取指定一个原点，半径内所有存活的玩家或者AI控制的角色列表，可设置忽略对象,归类为 游戏玩法机制
	UFUNCTION(BlueprintCallable, Category = "BaseAbilitySystemLibrary|GameplayMechanics")
	static void GetLivePlayersWithinRadius(const UObject* WorldContextObject, TArray<AActor*>& OutOverlappingActors,const TArray<AActor*>& ActorsToIgnore, float Radius, const FVector& SphereOrigin);
	//获取指定矩形范围内所有存活的玩家或者AI控制的角色列表，可设置忽略对象
	UFUNCTION(BlueprintCallable, Category = "BaseAbilitySystemLibrary|GameplayMechanics")
	static void GetLivePlayersWithinBox(const UObject* WorldContextObject, TArray<AActor*>& OutOverlappingActors, const TArray<AActor*>& ActorsToIgnore, const FVector& BoxExtent, const FVector& BoxOrigin, const FRotator& BoxRotation = FRotator::ZeroRotator);
	//获取最近的目标 MaxTargets-最大目标数、Actors-需要计算的演员数组，OutClosestTargets-计算结果返回的数组，Origin-计算的原点
	UFUNCTION(BlueprintCallable, Category = "BaseAbilitySystemLibrary|GameplayMechanics")
	static void GetClosestTargets(int32 MaxTargets, const TArray<AActor*>& Actors, TArray<AActor*>& OutClosestTargets,const FVector& Origin);
	
	//判断攻击者和被攻击对象是否是盟友
	UFUNCTION(BlueprintPure, Category = "BaseAbilitySystemLibrary|GameplayMechanics")
	static bool IsNotFriend(AActor* FirstActor, AActor* SecondActor);
	
	//根据给定的 前向向量、轴向量、角度、发射数量，生成均匀分布的 <旋转器数组> 通用用于发射技能
	UFUNCTION(BlueprintPure, Category = "BaseAbilitySystemLibrary|DamageEffect")
	static TArray<FRotator> EvenlySpacedRotators(const FVector& Forward, const FVector& Axis, float Spread, int32 NumRotators);
	
	//根据给定的 前向向量、轴向量、角度、发射数量，生成均匀分布的 <方向向量数组> 通用用于发射技能
	UFUNCTION(BlueprintPure, Category = "BaseAbilitySystemLibrary|DamageEffect")
	static TArray<FVector> EvenlySpacedVectors(const FVector& Forward, const FVector& Axis, float Spread, int32 NumVectors);
	
	//智能目标选择和转向 - 优先使用传入的目标，如果没有则尝试获取玩家选中的目标，并让玩家转向目标
	UFUNCTION(BlueprintPure, Category = "BaseAbilitySystemLibrary|TargetSelection")
	static bool GetSmartTargetAndRotatePlayer(const UObject* WorldContextObject, AActor* SourceAvatarActor, AActor* InputTarget, const FVector& DefaultTargetLocation, AActor*& OutFinalTarget, FVector& OutFinalTargetLocation);
	
	// 让玩家角色转向目标（简化版转向函数）
	UFUNCTION(BlueprintCallable, Category = "BaseAbilitySystemLibrary|TargetSelection")
	static FVector RotatePlayerToTarget(AActor* SourceAvatarActor, AActor* TargetActor,FVector& TargetLocation, float ToleranceDegrees = 5.0f);
	
	// 直接从传入的 Avatar 角色获取当前锁定目标（简单版）
	//bFindTarget 是否自动寻找敌人，bAutoLock 是否自动锁定, bDamageEffect 是否是伤害技能（如果是治疗技能可以给盟友用）
	UFUNCTION(BlueprintPure, Category = "BaseAbilitySystemLibrary|TargetSelection")
	static AActor* GetSelectedTargetFromAvatar(AActor* SourceAvatarActor, AActor* InputTarget, bool bNeedTarget, bool bFindTarget,bool bAutoLock, bool bDamageEffect);
	
	
	//应用伤害效果，异常伤害等
	UFUNCTION(BlueprintCallable, Category = "BaseAbilitySystemLibrary|DamageEffect")
	static FGameplayEffectContextHandle ApplyDamageEffect(const FDamageEffectParams& DamageEffectParams);
	
	//根据怪物职业角色和等级，获取当前怪物的修为值对应ct表奖励
	static int32 GetXPRewardForClassAndLevel(const UObject* WorldContextObject,ECharacterClass CharacterClass, int32 CharacterLevel);
	//根据怪物职业角色和等级，获取当前怪物的灵气值对应ct表奖励
	static int32 GetLingQiRewardForClassAndLevel(const UObject* WorldContextObject,ECharacterClass CharacterClass, int32 CharacterLevel);

	/*
	 * 用于在创建子类二段伤害时 设置的 伤害效果参数 DamageEffectParams
	 */
	//设置二段伤害目标的能力系统
	UFUNCTION(BlueprintCallable, Category = "BaseAbilitySystemLibrary|DamageEffect")
	static void SetTargetAbilitySystemComponent(UPARAM(ref) FDamageEffectParams& DamageEffectParams, UAbilitySystemComponent* InASC);
	//设置二段伤害径向伤害参数
	UFUNCTION(BlueprintCallable, Category = "BaseAbilitySystemLibrary|DamageEffect")
	static void SetIsRadialDamageEffectParam(UPARAM(ref) FDamageEffectParams& DamageEffectParams, bool bIsRadial, float InnerRadius, float OuterRadius, FVector Origin);
	//设置二段伤害击退参数 传入击退方向 ， Magnitude 默认0 如果不等于0 则使用传入的Magnitude计算击退
	UFUNCTION(BlueprintCallable, Category = "BaseAbilitySystemLibrary|DamageEffect")
	static void SetKnockbackEffectParam(UPARAM(ref) FDamageEffectParams& DamageEffectParams, FVector KnockbackDirection, float Magnitude = 0.f);
	//设置二段伤害死亡冲击参数 传入冲击方向， Magnitude 默认0 
	UFUNCTION(BlueprintCallable, Category = "BaseAbilitySystemLibrary|DamageEffect")
	static void SetDeathImpulseEffectParam(UPARAM(ref) FDamageEffectParams& DamageEffectParams, FVector ImpulseDirection, float Magnitude = 0.f);
};
